package com.example.springboot.ytest.ytool;

import java.lang.reflect.Method;
import java.util.*;

public class ArrayUtil {

	public static <T> Set<String> getIds(List<T> list, String fieldName) {
		if (list == null) {
			return null;
		}
		Set<String> ids = new HashSet<>();
		for (Object object : list) {
			Object object2 = getFieldValueByName(fieldName, object);
			ids.add(String.valueOf(object2));
		}
		return ids;
	}

	public static List<Integer> list2Integer(Collection<?> list, String fieldName) {
		if (list == null) {
			return new ArrayList<>();
		}
		Set<Integer> ids = new HashSet<>();
		for (Object object : list) {
			Object object2 = getFieldValueByName(fieldName, object);
			if (object2 != null) {
				ids.add((Integer) object2);
			}
		}
		return new ArrayList<>(ids);
	}

	public static Object[] list2Object(List<?> list, String fieldName) {
		if (list == null) {
			return null;
		}
		Set<Object> values = new HashSet<>();
		for (Object object : list) {
			Object fieldValue = getFieldValueByName(fieldName, object);
			values.add(fieldValue);
		}
		return values.toArray(new Object[values.size()]);
	}

	public static List<String> list2String(List<?> list, String fieldName) {
		if (list == null) {
			return null;
		}
		Set<String> ids = new HashSet<>();
		for (Object object : list) {
			Object object2 = getFieldValueByName(fieldName, object);
			ids.add((String) object2);
		}
		return new ArrayList<>(ids);
	}

	private static Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + fieldName.substring(1);
			Method method = o.getClass().getMethod(getter, new Class[] {});
			Object value = method.invoke(o, new Object[] {});
			return value;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static List<String> Intger2String(List<Integer> list) {
		List<String> strings = new ArrayList<>();
		for (Integer integer : list) {
			strings.add(String.valueOf(integer));
		}
		return strings;
	}

	public static String random() {
		Random randomNumber = new Random();
		int i = randomNumber.nextInt(100) + 100;
		return i + "";
	}
	
	/**
	 * 将容器中的对象按 id 放到 HashMap 中
	 * 因此 T 必须有  getId 这个方法，如果 id 不唯一，值会被覆盖 
	 * E 为 id 类型, 最好是 Integer 或 Long
	 * @return
	 */
	public static <T,E> Map<E, T> IterableToHashMapById(Iterable<T> it) {
	    return IterableToHashMap(it, "getId");
	}
	
	public static <T,E> Map<E, T> IterableToHashMap(Iterable<T> it, String methodName) {
        Map<E, T> result = new HashMap<E, T>(); 
        try {
            for(T obj: it){
              Method method = obj.getClass().getMethod(methodName, new Class[] {});
              @SuppressWarnings("unchecked")
              E id = (E)method.invoke(obj, new Object[] {});
              result.put(id, obj);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            return result; 
        }
        return result;
    }
	
	 /**
     * 将容器中的对象按 id 放到 HashMap 中
     * 因此 T 必须有  getId 这个方法，id 可以重复
     * E 为 id 类型, 最好是 Integer 或 Long
     * @return
     */
	public static <T,E> Map<E, List<T>> IterableToHashMapListById(Iterable<T> it) {
        return IterableToHashMapList(it, "getId");
    }
	
	public static <T,E> Map<E, List<T>> IterableToHashMapList(Iterable<T> it, String methodName) {
        Map<E, List<T>> result = new HashMap<E, List<T>>(); 
        try {
            for(T obj: it){
              Method method = obj.getClass().getMethod(methodName, new Class[] {});
              @SuppressWarnings("unchecked")
              E id = (E)method.invoke(obj, new Object[] {});
              List<T> tList = result.get(id);
              if( null==tList )
                  tList = new LinkedList<>();
              tList.add(obj);
              result.put(id, tList);
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            return result; 
        }
        return result;
    }

	public static void main(String[] args) {
        class ABC{
            int id;
            String sId;
            String string;
            public ABC(int id, String sId, String string) {
                super();
                this.id = id;
                this.string = string;
                this.sId = sId;
            }
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public String getString() {
                return string;
            }
            public void setString(String string) {
                this.string = string;
            }
            public String getsId() {
                return sId;
            }
            public void setsId(String sId) {
                this.sId = sId;
            }
            @Override
            public String toString() {
                return "ABC [id=" + id + ", sId=" + sId + ", string=" + string + "]";
            }
            
        }
        
        List<ABC> abcList = new LinkedList<>();
        abcList.add(new ABC(1, "a", "123"));
        abcList.add(new ABC(2, "b", "哈哈"));
        abcList.add(new ABC(3, "c", "你好"));
        abcList.add(new ABC(3, "b", "你好变了"));
        
        Map<Integer, ABC> abcMap = IterableToHashMapById(abcList);
        System.out.println(abcMap);
        Map<Integer, List<ABC>> abcMapList = IterableToHashMapListById(abcList);
        System.out.println(abcMapList);
        
        abcMap = IterableToHashMap(abcList,"getsId");
        System.out.println(abcMap);
        abcMapList = IterableToHashMapList(abcList,"getsId");
        System.out.println(abcMapList);
    }
}
